package com.yanfan.energy.service.impl;

import cn.hutool.core.util.StrUtil;
import com.yanfan.common.core.domain.entity.SysUser;
import com.yanfan.common.utils.SecurityUtils;
import com.yanfan.energy.domain.*;
import com.yanfan.energy.domain.enums.BatchesStatus;
import com.yanfan.energy.domain.enums.EnergyClassifyEnum;
import com.yanfan.energy.domain.enums.EnergyTypeEnum;
import com.yanfan.energy.domain.enums.TimeDimensionEnum;
import com.yanfan.energy.mapper.ConsumptionDao;
import com.yanfan.energy.mapper.EquipmentConsumptionDao;
import com.yanfan.energy.service.ConsumptionService;
import com.yanfan.energy.util.DateUtils;
import com.github.pagehelper.PageHelper;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * @Author huan
 * @Description 能源监控相关实现类
 * @ClassName 2023年03月22日 15:18:00
 * @Version 1.0
 **/
@Service
public class ConsumptionServiceImpl implements ConsumptionService {


    @Resource
    private ConsumptionDao consumptionDao;

    @Resource
    private EquipmentConsumptionDao equipmentConsumptionDao;

    public static Date setDateMinuteSecond(Date date) {
        // 创建 Calendar 对象
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 将时间增加一天
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }

    private static EquipmentEnergyBaseResp getMonths(Integer type, Long deviceId, String deviceName) {
        EquipmentEnergyBaseResp equipmentEnergyBaseResp = new EquipmentEnergyBaseResp();
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, type);
        ArrayList<EquipmentEnergyBaseResp.EnergyDate> energyDates = new ArrayList<>();
        for (int month = 0; month < 12; month++) {
            calendar.set(Calendar.MONTH, month);

            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM");
            Date currentDate = calendar.getTime();
            String formattedDate = dateFormat.format(currentDate);

            EquipmentEnergyBaseResp.EnergyDate energyDate = new EquipmentEnergyBaseResp.EnergyDate();
            energyDate.setCreatedDate(formattedDate);
            energyDates.add(energyDate);
        }
        equipmentEnergyBaseResp.setType(type);
        String[] split = energyDates.get(0).getCreatedDate().split("-");
        equipmentEnergyBaseResp.setTime(split[0]);
        equipmentEnergyBaseResp.setEnergyDateList(energyDates);
        equipmentEnergyBaseResp.setDeviceName(deviceName);
        equipmentEnergyBaseResp.setDeviceId(deviceId);
        return equipmentEnergyBaseResp;
    }

    private static EquipmentEnergyBaseResp getDays(Integer type, Long deviceId, String deviceName) {

        EquipmentEnergyBaseResp equipmentEnergyBaseResp = new EquipmentEnergyBaseResp();
        ArrayList<EquipmentEnergyBaseResp.EnergyDate> energyDates = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();

        // 设置月份偏移量
        calendar.add(Calendar.MONTH, type);

        // 获取当前月的天数
        int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

        // 格式化日期
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        // 获取当月或下月的所有天数
        for (int day = 1; day <= 31; day++) {

            String formattedDate = null;
            if (day <= daysInMonth) {
                calendar.set(Calendar.DAY_OF_MONTH, day);
                Date currentDate = calendar.getTime();
                formattedDate = dateFormat.format(currentDate);
            } else {
                Date currentDate1 = calendar.getTime();
                DateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM");
                String format = dateFormat1.format(currentDate1);
                formattedDate = format + "-" + day;
            }


            EquipmentEnergyBaseResp.EnergyDate energyDate = new EquipmentEnergyBaseResp.EnergyDate();
            energyDate.setCreatedDate(formattedDate);
            energyDates.add(energyDate);
        }

        equipmentEnergyBaseResp.setType(type);
        String[] split = energyDates.get(0).getCreatedDate().split("-");
        equipmentEnergyBaseResp.setTime(split[1]);
        equipmentEnergyBaseResp.setDeviceId(deviceId);
        equipmentEnergyBaseResp.setDeviceName(deviceName);
        equipmentEnergyBaseResp.setEnergyDateList(energyDates);
        return equipmentEnergyBaseResp;
    }

    /**
     * 返回本周 周一和周日的日期
     *
     * @return
     */
    public static Map<String, Date> getBeforeDay(Map<String, ConsumptionProportion> reqMap) {
        Map<String, Date> map = new HashMap();
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 0);
        map.put("endDate", cal.getTime());

        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - 7);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        map.put("beginDate", calendar.getTime());

        SimpleDateFormat sdf = new SimpleDateFormat("dd");
        for (int i = 1; i <= 7; i++) {
            calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + 1);
            reqMap.put(sdf.format(calendar.getTime()), new ConsumptionProportion());
        }
        return map;
    }

    /**
     * list 转Map
     *
     * @param list
     * @param keyExtractor
     * @param <T>
     * @return
     */
    public static <T> Map<Object, List<T>> groupBy(List<T> list, Function<T, Object> keyExtractor) {
        return list.stream().collect(Collectors.groupingBy(keyExtractor));
    }

    /**
     * 新的代码
     *
     * @param equipmentEnergyParam
     * @return
     */
    @Override
    public List<EquipmentConsumptionDto> selectequipmentEnergy(EquipmentEnergyParam equipmentEnergyParam) {
        // 判断查询那张表 hour 、day、month 、year
        if (equipmentEnergyParam != null && equipmentEnergyParam.getEnd() != null) {
            // 月
            if (equipmentEnergyParam.getDateType().equals(3)) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(equipmentEnergyParam.getEnd());
                int year = calendar.get(Calendar.YEAR);
                int month = calendar.get(Calendar.MONTH) + 1;
                equipmentEnergyParam.setEnd(DateUtils.getLastDayOfMonth(year, month));
            }
            equipmentEnergyParam.setEnd(DateUtils.changeTheEnd(equipmentEnergyParam.getEnd()));
        } else {
            // 如果只选了时间维度 没有选时间范围  默认查当天、当月、当年的数据
            setTimeDimensionDate(equipmentEnergyParam);
        }
        PageHelper.startPage(equipmentEnergyParam.getPageNum(), equipmentEnergyParam.getPageSize());
        return consumptionDao.selectequipmentEnergy(equipmentEnergyParam);
    }

    /**
     * 设置时间
     *
     * @param equipmentEnergyParam
     */
    private void setTimeDimensionDate(EquipmentEnergyParam equipmentEnergyParam) {
        int year = Calendar.getInstance().get(Calendar.YEAR);
        int month = Calendar.getInstance().get(Calendar.MONTH) + 1;
        switch (equipmentEnergyParam.getDateType()) {
            case 1:
                equipmentEnergyParam.setBegin(DateUtils.getAppointDayTimestamp(0));
                equipmentEnergyParam.setEnd(DateUtils.changeTheEnd(new Date()));
                break;
            case 2:
                equipmentEnergyParam.setBegin(DateUtils.getAppointMonthTimestamp(0));
                equipmentEnergyParam.setEnd(DateUtils.changeTheEnd(DateUtils.getLastDayOfMonth(year, month)));
                break;
            case 3:
                equipmentEnergyParam.setBegin(DateUtils.getAppointYearTimestamp(0));
                equipmentEnergyParam.setEnd(DateUtils.changeTheEnd(DateUtils.getLastDayOfYear(year)));
                break;
        }
    }

    /**
     * 图表 相关
     *
     * @param equipmentEnergyParam
     * @return
     */
    @Override
    public Map equipmentChartEnergy(EquipmentEnergyParam equipmentEnergyParam, Integer type) {
        // 判断查询那张表 hour 、day、month 、year
        if (equipmentEnergyParam != null && equipmentEnergyParam.getEnd() != null) {
            // 月
            if (equipmentEnergyParam.getDateType().equals(3)) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(equipmentEnergyParam.getEnd());
                int year = calendar.get(Calendar.YEAR);
                int month = calendar.get(Calendar.MONTH) + 1;
                equipmentEnergyParam.setEnd(DateUtils.getLastDayOfMonth(year, month));
            }
            equipmentEnergyParam.setEnd(DateUtils.changeTheEnd(equipmentEnergyParam.getEnd()));
        } else {
            // 如果只选了时间维度 没有选时间范围  默认查当天、当月、当年的数据
            setTimeDimensionDate(equipmentEnergyParam);
        }
        /**
         * 要返回给前端的 数据
         */
        // 折线图
        Map<String, EquipmentConsumptionDto> energyMap = currentDateMap(equipmentEnergyParam.getDateType());

        // 饼图
        Map<String, Double> pieGraphMap = new HashMap<>();
        // this方法返回参数
        Map resMap = new HashMap();
        /**
         * 初始话 sql 请求参数
         */
        dataBaseRequestParam(equipmentEnergyParam, pieGraphMap);
        // 数据库数据
        List<EquipmentConsumptionDto> overallEnergyDTOS = consumptionDao.selectequipmentEnergyChart(equipmentEnergyParam);
        List<EquipmentConsumptionDto> overallEnergyDTOList = consumptionDao.selectequipmentEnergyChartByType(equipmentEnergyParam);
        if (overallEnergyDTOS == null || overallEnergyDTOS.isEmpty()) {
            resMap.put("brokenLine", energyMap);
            resMap.put("pieGraph", pieGraphMap);
            return resMap;
        }
        /***
         * 能耗相关的价格 用量
         */
        Map<String, PurchasingBody> purchasingBodyMap = null;
//        if(type!=2 ){
//            purchasingBodyMap = energyPriceWorkshop(equipmentEnergyParam);
//        }else {
//            purchasingBodyMap = energyPriceMapBuild(equipmentEnergyParam);
//        }


        // 折线图，计算24小时内、一个月内 、一年内的花费
        AllCostSum(overallEnergyDTOS, energyMap, purchasingBodyMap);
        // 初始化饼图数据
        pieGraphPackage(overallEnergyDTOList, pieGraphMap, purchasingBodyMap);
        resMap.put("brokenLine", energyMap);
        resMap.put("pieGraph", pieGraphMap);
        return resMap;
    }

    /**
     * 折线图 填充
     *
     * @param dateType 接口请求实体类
     */
    private Map<String, EquipmentConsumptionDto> currentDateMap(Integer dateType) {
        Map<String, EquipmentConsumptionDto> respMap = new LinkedHashMap<>();
        int compare = 0;
        int beginIndex = 1;
        if (TimeDimensionEnum.DAY.getCode().equals(dateType)) { // 日
            compare = 23;
            beginIndex = 0; // 日 要特意设置为0
        } else if (TimeDimensionEnum.MONTH.getCode().equals(dateType)) { //月
            compare = DateUtils.getDaysOfMonth(new Date());
        } else if (TimeDimensionEnum.YEAR.getCode().equals(dateType)) { // 年
            compare = 12;
        } else { // 日
            compare = 23;
            beginIndex = 0; // 日 要特意设置为0
        }
        for (int i = beginIndex; i <= compare; i++) {
            String key = String.valueOf(i);
            if (i < 10) {
                key = "0" + i;
            }
            respMap.put(key, new EquipmentConsumptionDto("init"));
        }
        return respMap;
    }

    @Override
    public List<EquipmentConsumptionHead> selectequipmentDown(EquipmentEnergyParam equipmentEnergyParam, Integer type) {
        if (equipmentEnergyParam != null && equipmentEnergyParam.getEnd() != null) {
            // 月
            if (equipmentEnergyParam.getDateType().equals(3)) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(equipmentEnergyParam.getEnd());
                int year = calendar.get(Calendar.YEAR);
                int month = calendar.get(Calendar.MONTH) + 1;
                equipmentEnergyParam.setEnd(DateUtils.getLastDayOfMonth(year, month));
            }
            equipmentEnergyParam.setEnd(DateUtils.changeTheEnd(equipmentEnergyParam.getEnd()));
        } else {
            // 如果只选了时间维度 没有选时间范围  默认查当天、当月、当年的数据
            setTimeDimensionDate(equipmentEnergyParam);
        }
        List<EquipmentConsumptionDto> equipmentConsumptionDtos = null;
        List<EquipmentConsumptionHead> heads = new ArrayList<>();
        if (type.equals(1)) {
            equipmentConsumptionDtos = consumptionDao.selectequipmentEnergy(equipmentEnergyParam);
        } else if (type.equals(2)) {
            equipmentConsumptionDtos = consumptionDao.workshopEnergy(equipmentEnergyParam);
        } else if (type.equals(3)) {
            equipmentConsumptionDtos = consumptionDao.buildingEnergy(equipmentEnergyParam);
        }
        if (CollectionUtils.isEmpty(equipmentConsumptionDtos)) {
            return heads;
        }
        for (EquipmentConsumptionDto equipmentConsumptionDto : equipmentConsumptionDtos) {
            EquipmentConsumptionHead head = new EquipmentConsumptionHead();
            head.setDeviceName(equipmentConsumptionDto.getDeviceName());
            head.setPowerConsumption(equipmentConsumptionDto.getPowerConsumption());
            head.setWaterConsumption(equipmentConsumptionDto.getWaterConsumption());
            head.setGasConsumption(equipmentConsumptionDto.getGasConsumption());
            head.setSpikesType(equipmentConsumptionDto.getSpikesType());
            head.setPeaksType(equipmentConsumptionDto.getPeaksType());
            head.setParityType(equipmentConsumptionDto.getParityType());
            head.setLowebbType(equipmentConsumptionDto.getLowebbType());
            head.setCoolingType(equipmentConsumptionDto.getCoolingType());
            head.setTapType(equipmentConsumptionDto.getTapType());
            head.setLnstrumentAirPressure(equipmentConsumptionDto.getLnstrumentAirPressure());
            head.setCleanCompressedAir(equipmentConsumptionDto.getCleanCompressedAir());
            head.setAirHotEnergy(equipmentConsumptionDto.getAirHotEnergy());
            head.setCreatedDate(equipmentConsumptionDto.getCreatedDate());
            head.setEquipmentConPrice(equipmentConsumptionDto.getEquipmentConPrice());
            heads.add(head);
        }
        return heads;
    }

    @Override
    public Map consumptionProportion() {
        Map<String, ConsumptionProportion> resMap = getInitMap();
        List<OperationCase> devOpsList = consumptionDao.devOpsList(consumptionProportionRequest());
        // 运维任务
        if (!CollectionUtils.isEmpty(devOpsList)) {
            for (OperationCase operationCase : devOpsList) {
                if (resMap.get(operationCase.getDate()) != null) {
                    if (BatchesStatus.FINISHED.getCode().equals(operationCase.getState())) {
                        Long finish = resMap.get(operationCase.getDate()).getFinish();
                        BigDecimal add = new BigDecimal(finish).add(new BigDecimal(operationCase.getNum()));
                        resMap.get(operationCase.getDate()).setFinish(add.longValue());
                    } else {
                        Long finish = resMap.get(operationCase.getDate()).getUnFinish();
                        BigDecimal add = new BigDecimal(finish).add(new BigDecimal(operationCase.getNum()));
                        resMap.get(operationCase.getDate()).setUnFinish(add.longValue());
                    }
                }
            }
        }
        // 车间和办公室的能源费用占比
        List<OperationCase> energyConsumptionList = consumptionDao.energyConsumptionList(consumptionProportionRequest());
        if (!CollectionUtils.isEmpty(energyConsumptionList)) {
            for (OperationCase operationCase : energyConsumptionList) {
                if (resMap.get(operationCase.getDate()) != null) {
                    if ("1".equals(operationCase.getType())) {
                        double office = resMap.get(operationCase.getDate()).getOffice();
                        BigDecimal add = new BigDecimal(office).add(new BigDecimal(operationCase.getPrice()));
                        resMap
                                .get(operationCase.getDate())
                                .setOffice(add.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                    } else {
                        double workshop = resMap.get(operationCase.getDate()).getWorkshop();
                        BigDecimal add = new BigDecimal(workshop).add(new BigDecimal(operationCase.getPrice()));
                        resMap
                                .get(operationCase.getDate())
                                .setWorkshop(add.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                    }
                }
            }
        }

        return resMap;
    }

    @Override
    public Map consumptionProportion2() {
        Map<String, ConsumptionProportion> resMap = new LinkedHashMap<>();
        DeviceChartRequest deviceChartRequest = consumptionProportionReq(resMap, getBeforeDay(resMap));
        List<OperationCase> devOpsList = consumptionDao.devOpsList2(deviceChartRequest);
        // 运维任务
        if (!CollectionUtils.isEmpty(devOpsList)) {
            for (OperationCase operationCase : devOpsList) {
                if (resMap.get(operationCase.getDate()) != null) {
                    if (BatchesStatus.FINISHED.getCode().equals(operationCase.getState())) {
                        Long finish = resMap.get(operationCase.getDate()).getFinish();
                        BigDecimal add = new BigDecimal(finish).add(new BigDecimal(operationCase.getNum()));
                        resMap.get(operationCase.getDate()).setFinish(add.longValue());
                    } else {
                        Long finish = resMap.get(operationCase.getDate()).getUnFinish();
                        BigDecimal add = new BigDecimal(finish).add(new BigDecimal(operationCase.getNum()));
                        resMap.get(operationCase.getDate()).setUnFinish(add.longValue());
                    }
                }
            }
        }


        // 车间和办公室的能源费用占比
        List<OperationCase> energyConsumptionList = consumptionDao.energyConsumptionList2(deviceChartRequest);
        if (!CollectionUtils.isEmpty(energyConsumptionList)) {
            for (OperationCase operationCase : energyConsumptionList) {
                if (resMap.get(operationCase.getDate()) != null) {
                    if ("1".equals(operationCase.getType())) {
                        double office = resMap.get(operationCase.getDate()).getOffice();
                        BigDecimal add = new BigDecimal(office).add(new BigDecimal(operationCase.getPrice()));
                        resMap
                                .get(operationCase.getDate())
                                .setOffice(add.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                    } else {
                        double workshop = resMap.get(operationCase.getDate()).getWorkshop();
                        BigDecimal add = new BigDecimal(workshop).add(new BigDecimal(operationCase.getPrice()));
                        resMap
                                .get(operationCase.getDate())
                                .setWorkshop(add.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                    }
                }
            }
        }
        return resMap;
    }

    @Override
    public List<EquipmentEnergyBaseResp> baseYear(EquipmentEnergyBaseReq equipmentEnergyBaseReq) {
        ArrayList<EquipmentEnergyBaseResp> equipmentEnergyBaseRespList = new ArrayList<>();

        Date currentYearEndDate = null;
        Date lastYearStartDate = null;

        if (equipmentEnergyBaseReq.getDateType() == 0) {
            // 获取当前年的最后一天 23:59:59
            Calendar currentYearEnd = Calendar.getInstance();
            currentYearEnd.set(Calendar.DAY_OF_YEAR, currentYearEnd.getActualMaximum(Calendar.DAY_OF_YEAR));
            currentYearEnd.set(Calendar.HOUR_OF_DAY, 23);
            currentYearEnd.set(Calendar.MINUTE, 59);
            currentYearEnd.set(Calendar.SECOND, 59);
            currentYearEndDate = currentYearEnd.getTime();

            // 获取去年的第一天 00:00:00
            Calendar lastYearStart = Calendar.getInstance();
            lastYearStart.add(Calendar.YEAR, -1);
            lastYearStart.set(Calendar.DAY_OF_YEAR, lastYearStart.getActualMinimum(Calendar.DAY_OF_YEAR));
            lastYearStart.set(Calendar.HOUR_OF_DAY, 0);
            lastYearStart.set(Calendar.MINUTE, 0);
            lastYearStart.set(Calendar.SECOND, 0);
            lastYearStartDate = lastYearStart.getTime();


            //今年的数据
            EquipmentEnergyBaseResp equipmentEnergyBaseResp1 = getMonths(0, equipmentEnergyBaseReq.getDeviceId(), equipmentEnergyBaseReq.getDeviceName());
            equipmentEnergyBaseRespList.add(equipmentEnergyBaseResp1);

            //去年的数据
            EquipmentEnergyBaseResp equipmentEnergyBaseResp2 = getMonths(-1, equipmentEnergyBaseReq.getDeviceId(), equipmentEnergyBaseReq.getDeviceName());
            equipmentEnergyBaseRespList.add(equipmentEnergyBaseResp2);

        } else {

            // 获取当月的最后一天 23:59:59
            Calendar currentMonthEnd = Calendar.getInstance();
            currentMonthEnd.set(Calendar.DAY_OF_MONTH, currentMonthEnd.getActualMaximum(Calendar.DAY_OF_MONTH));
            currentMonthEnd.set(Calendar.HOUR_OF_DAY, 23);
            currentMonthEnd.set(Calendar.MINUTE, 59);
            currentMonthEnd.set(Calendar.SECOND, 59);
            currentYearEndDate = currentMonthEnd.getTime();

            // 获取上月的第一天 00:00:00
            Calendar lastMonthStart = Calendar.getInstance();
            lastMonthStart.add(Calendar.MONTH, -1);
            lastMonthStart.set(Calendar.DAY_OF_MONTH, 1);
            lastMonthStart.set(Calendar.HOUR_OF_DAY, 0);
            lastMonthStart.set(Calendar.MINUTE, 0);
            lastMonthStart.set(Calendar.SECOND, 0);
            lastYearStartDate = lastMonthStart.getTime();

            //本月的数据
            EquipmentEnergyBaseResp equipmentEnergyBaseResp1 = getDays(0, equipmentEnergyBaseReq.getDeviceId(), equipmentEnergyBaseReq.getDeviceName());
            equipmentEnergyBaseRespList.add(equipmentEnergyBaseResp1);

            //上月的数据
            EquipmentEnergyBaseResp equipmentEnergyBaseResp2 = getDays(-1, equipmentEnergyBaseReq.getDeviceId(), equipmentEnergyBaseReq.getDeviceName());
            equipmentEnergyBaseRespList.add(equipmentEnergyBaseResp2);

        }


        //获取设备能源数据结果
        List<EquipmentEnergyBaseParam> equipmentEnergyBaseParams = consumptionDao.baseYear(lastYearStartDate, currentYearEndDate, equipmentEnergyBaseReq.getDeviceId(), equipmentEnergyBaseReq.getDateType());

        if (!CollectionUtils.isEmpty(equipmentEnergyBaseParams)) {

            for (EquipmentEnergyBaseResp equipmentEnergyBaseResp : equipmentEnergyBaseRespList) {
                List<EquipmentEnergyBaseResp.EnergyDate> energyDates = equipmentEnergyBaseResp.getEnergyDateList();
                Map<String, EquipmentEnergyBaseResp.EnergyDate> energyDateMap = energyDates
                        .stream()
                        .collect(Collectors.toMap(EquipmentEnergyBaseResp.EnergyDate::getCreatedDate, Function.identity()));
                List<String> createdDateList = energyDates
                        .stream()
                        .map(EquipmentEnergyBaseResp.EnergyDate::getCreatedDate)
                        .collect(Collectors.toList());
                //设备能源数据处理
                Map<String, List<EquipmentEnergyBaseParam>> collect = equipmentEnergyBaseParams
                        .stream()
                        .collect(Collectors.groupingBy(EquipmentEnergyBaseParam::getDeviceName));
                for (String deviceName : collect.keySet()) {
                    List<EquipmentEnergyBaseParam> equipmentEnergyBaseParams1 = collect.get(deviceName);

                    equipmentEnergyBaseParams1.forEach(equipmentEnergyBaseParam -> {

                        BigDecimal b1 = new BigDecimal(Double.toString(equipmentEnergyBaseParam.getErergyConsumption()));
                        BigDecimal b2 = new BigDecimal(Double.toString(equipmentEnergyBaseParam.getGasConsumption()));
                        BigDecimal b3 = new BigDecimal(Double.toString(equipmentEnergyBaseParam.getPowerConsumption()));
                        BigDecimal b4 = new BigDecimal(Double.toString(equipmentEnergyBaseParam.getWaterConsumption()));

                        double totalEnergy = b1.add(b2).add(b3).add(b4).doubleValue();

                        if (createdDateList.contains(equipmentEnergyBaseParam.getCreatedDate())) {
                            EquipmentEnergyBaseResp.EnergyDate energyDate = energyDateMap.get(equipmentEnergyBaseParam.getCreatedDate());
                            energyDate.setTotalEnergy(totalEnergy);
                        }

                    });
                }
            }


        }
        return equipmentEnergyBaseRespList;

    }

    private DeviceChartRequest consumptionProportionRequest() {
        DeviceChartRequest request = new DeviceChartRequest();
        SysUser user = SecurityUtils.getLoginUser().getUser();
        if (!user.isAdmin()) {
            request.setUserId(user.getUserId());
        }
        Map<String, Date> weekDate = DateUtils.getWeekDate();
        request.setBeginDate(weekDate.get("beginDate"));
        request.setEndDate(weekDate.get("endDate"));
        request.setDateFormatGroup("%Y-%m-%d");
        return request;
    }

    private DeviceChartRequest consumptionProportionReq(Map<String, ConsumptionProportion> map, Map<String, Date> weekDate) {
        DeviceChartRequest request = new DeviceChartRequest();
        SysUser user = SecurityUtils.getLoginUser().getUser();
        if (!user.isAdmin()) {
            request.setUserId(user.getUserId());
        }
        request.setBeginDate(weekDate.get("beginDate"));
        request.setEndDate(weekDate.get("endDate"));
        request.setDateFormatGroup("%Y-%m-%d");
        return request;
    }

    private Map<String, ConsumptionProportion> getInitMap() {
        Map<String, ConsumptionProportion> respMap = new LinkedHashMap<>();
        respMap.put("周一", new ConsumptionProportion());
        respMap.put("周二", new ConsumptionProportion());
        respMap.put("周三", new ConsumptionProportion());
        respMap.put("周四", new ConsumptionProportion());
        respMap.put("周五", new ConsumptionProportion());
        respMap.put("周六", new ConsumptionProportion());
        respMap.put("周日", new ConsumptionProportion());
        return respMap;
    }

    private void dataBaseRequestParam(EquipmentEnergyParam equipmentEnergyParam, Map<String, Double> pieGraphMap) {
        equipmentEnergyParam.setPageNum(null);
        equipmentEnergyParam.setPageSize(null);
        equipmentEnergyParam.setType(null); // 前端传值有问题，这里补一下
        convertEnergyType(equipmentEnergyParam, pieGraphMap);
        // 判断查询那张表 hour 、day、month 、year
        findEnergyTable(equipmentEnergyParam);
    }

    /**
     * 车间能源监控
     *
     * @param equipmentEnergyParam
     * @return
     */
    @Override
    public List<EquipmentConsumptionDto> workshopEnergy(EquipmentEnergyParam equipmentEnergyParam) {
        if (equipmentEnergyParam != null && equipmentEnergyParam.getEnd() != null) {
            // 月
            if (equipmentEnergyParam.getDateType().equals(3)) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(equipmentEnergyParam.getEnd());
                int year = calendar.get(Calendar.YEAR);
                int month = calendar.get(Calendar.MONTH) + 1;
                equipmentEnergyParam.setEnd(DateUtils.getLastDayOfMonth(year, month));
            }
            equipmentEnergyParam.setEnd(DateUtils.changeTheEnd(equipmentEnergyParam.getEnd()));
        } else {
            // 如果只选了时间维度 没有选时间范围  默认查当天、当月、当年的数据
            setTimeDimensionDate(equipmentEnergyParam);
        }
        // 判断查询那张表 hour 、day、month 、year
//        findEnergyTable(equipmentEnergyParam);
        PageHelper.startPage(equipmentEnergyParam.getPageNum(), equipmentEnergyParam.getPageSize());
        return consumptionDao.workshopEnergy(equipmentEnergyParam);
    }

    /**
     * 楼栋添加能源数据
     *
     * @param equipmentEnergyParam
     * @return
     */
    @Override
    public List<EquipmentConsumptionDto> buildingEnergy(EquipmentEnergyParam equipmentEnergyParam) {
        if (equipmentEnergyParam != null && equipmentEnergyParam.getEnd() != null) {
            // 月
            if (equipmentEnergyParam.getDateType().equals(3)) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(equipmentEnergyParam.getEnd());
                int year = calendar.get(Calendar.YEAR);
                int month = calendar.get(Calendar.MONTH) + 1;
                equipmentEnergyParam.setEnd(DateUtils.getLastDayOfMonth(year, month));
            }
            equipmentEnergyParam.setEnd(DateUtils.changeTheEnd(equipmentEnergyParam.getEnd()));
        } else {
            // 如果只选了时间维度 没有选时间范围  默认查当天、当月、当年的数据
            setTimeDimensionDate(equipmentEnergyParam);
        }
        // 判断查询那张表 hour 、day、month 、year
//        findEnergyTable(equipmentEnergyParam);
        PageHelper.startPage(equipmentEnergyParam.getPageNum(), equipmentEnergyParam.getPageSize());
        List<EquipmentConsumptionDto> dataData = consumptionDao.buildingEnergy(equipmentEnergyParam);
        if (CollectionUtils.isEmpty(dataData)) {
            return new ArrayList<>();
        }
        return dataData;
    }

    /**
     * 首页能耗统计
     *
     * @return (三生接口)
     */
    @Override
    public EnergyConsumption energyConsumption() {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        if (user.isAdmin()) {
            EnergyConsumption energyConsumption = consumptionDao.energyConsumption();
            energyConsumption.filter();
            return energyConsumption;
        }

        EnergyConsumption energyConsumption = consumptionDao.energyConsumptionIsNotAdmin(user.getUserId(), getAncestor());
        energyConsumption.filter();
        return energyConsumption;
    }

    /**
     * // 获取当前登陆用户二级部门 ID
     *
     * @return
     */
    private String getAncestor() {
        String ancestors = equipmentConsumptionDao.selectDeptAncestors(SecurityUtils.getUserId());
        if (ancestors.contains("100,")) { // 本部门是不是二级部门
            String[] split = ancestors.split(",");
            return split[2];
        } else {
            return String.valueOf(SecurityUtils.getDeptId());
        }
    }

    /**
     * 饼图
     *
     * @param overallEnergyDTOS
     * @param pieGraphMap
     */
    private void pieGraphPackage(List<EquipmentConsumptionDto> overallEnergyDTOS, Map<String, Double> pieGraphMap, Map<String, PurchasingBody> purchasingBodyMap) {
        for (EquipmentConsumptionDto overallEnergyDTO : overallEnergyDTOS) {
            pieGraphMap.put(EnergyTypeEnum.getDescByType(overallEnergyDTO.getType()), overallEnergyDTO.getEquipmentConPrice());
        }
    }

    /**
     * 计算24小时内（每小时）、一个月内（每天） 、一年内的花费  （每月）
     *
     * @param overallEnergyDTOS
     * @param energyMap
     */
    private void AllCostSum(List<EquipmentConsumptionDto> overallEnergyDTOS, Map<String, EquipmentConsumptionDto> energyMap, Map<String, PurchasingBody> purchasingBodyMap) {
        for (EquipmentConsumptionDto entry : overallEnergyDTOS) {
            if (energyMap.containsKey(entry.getCreatedDate())) {
                energyMap.put(entry.getCreatedDate(), entry);
            }
        }
    }

    // 请求参数 根据 energyType 转成type 或者大类
    public void convertEnergyType(EquipmentEnergyParam param, Map<String, Double> pieGraphMap) {
        if (StrUtil.isEmpty(param.getEnergyType())) {
            for (EnergyTypeEnum item : EnergyTypeEnum.values()) {
                pieGraphMap.put(item.getDesc(), 0.0);
            }
            return;
        }
        switch (param.getEnergyType()) {
            case "powerConsumption":
                param.setClassifyId(EnergyClassifyEnum.ELECTRICITY.getCode());
                // 塞初始值
                pieGraphMap.put(EnergyTypeEnum.SPIKES.getDesc(), 0.0);
                pieGraphMap.put(EnergyTypeEnum.PEAKS.getDesc(), 0.0);
                pieGraphMap.put(EnergyTypeEnum.PARITY.getDesc(), 0.0);
                pieGraphMap.put(EnergyTypeEnum.LOWEBB.getDesc(), 0.0);
                break;
            case "waterConsumption":
                param.setClassifyId(EnergyClassifyEnum.WATER.getCode());
                // 塞初始值
                pieGraphMap.put(EnergyTypeEnum.CODE_COOLING_WATER.getDesc(), 0.0);
                pieGraphMap.put(EnergyTypeEnum.TAP.getDesc(), 0.0);
                pieGraphMap.put(EnergyTypeEnum.PURE_WATER.getDesc(), 0.0);
                break;
            case "gasConsumption":
                param.setClassifyId(EnergyClassifyEnum.AIR.getCode());
                pieGraphMap.put(EnergyTypeEnum.COMPRESS.getDesc(), 0.0);
                pieGraphMap.put(EnergyTypeEnum.CARBON_DIOXIDE.getDesc(), 0.0);
                pieGraphMap.put(EnergyTypeEnum.VAPOUR.getDesc(), 0.0);
                break;
            case "spikesType":
                param.setClassifyId(EnergyClassifyEnum.ELECTRICITY.getCode());
                param.setType(EnergyTypeEnum.SPIKES.getCode());
                pieGraphMap.put(EnergyTypeEnum.SPIKES.getDesc(), 0.0);
                break;
            case "peaksType":
                param.setClassifyId(EnergyClassifyEnum.ELECTRICITY.getCode());
                param.setType(EnergyTypeEnum.PEAKS.getCode());
                pieGraphMap.put(EnergyTypeEnum.PEAKS.getDesc(), 0.0);
                break;
            case "parityType":
                param.setClassifyId(EnergyClassifyEnum.ELECTRICITY.getCode());
                param.setType(EnergyTypeEnum.PARITY.getCode());
                pieGraphMap.put(EnergyTypeEnum.PARITY.getDesc(), 0.0);
                break;
            case "lowebbType":
                param.setClassifyId(EnergyClassifyEnum.ELECTRICITY.getCode());
                param.setType(EnergyTypeEnum.LOWEBB.getCode());
                pieGraphMap.put(EnergyTypeEnum.LOWEBB.getDesc(), 0.0);
                break;
            case "coolingType":
                param.setClassifyId(EnergyClassifyEnum.WATER.getCode());
                param.setType(EnergyTypeEnum.CODE_COOLING_WATER.getCode());
                pieGraphMap.put(EnergyTypeEnum.CODE_COOLING_WATER.getDesc(), 0.0);
                break;
            case "softeningType":
                param.setClassifyId(EnergyClassifyEnum.WATER.getCode());
                param.setType(EnergyTypeEnum.TAP.getCode());
                pieGraphMap.put(EnergyTypeEnum.TAP.getDesc(), 0.0);
                break;
        }
    }

    /**
     * 根据将请求参数的 开始和结束日期 选择要查询的能源表
     *
     * @param equipmentEnergyParam
     */
    private void findEnergyTable(EquipmentEnergyParam equipmentEnergyParam) {
        if (equipmentEnergyParam.getEnd() != null) {
            equipmentEnergyParam.setEnd(setDateMinuteSecond(equipmentEnergyParam.getEnd()));
        }
        if (equipmentEnergyParam.getDateType() != null) {
            switch (equipmentEnergyParam.getDateType()) {
                case 1:
                    equipmentEnergyParam.setTableType("hour");
                    break;
                case 2:
                    equipmentEnergyParam.setTableType("day");
                    break;
                case 3:
                    equipmentEnergyParam.setTableType("month");
                    break;
                case 4:
                    equipmentEnergyParam.setTableType("year");
                    break;
            }
            return;
        }
        Date begin = equipmentEnergyParam.getBegin();
        if (begin == null || equipmentEnergyParam.getEnd() == null) {
            equipmentEnergyParam.setTableType("hour");
            return;
        }

        // 默认为 hour实时表
        equipmentEnergyParam.setTableType("hour");

    }

    @Cacheable("purchaseEnergy-workshop")
    public Map<String, PurchasingBody> energyPriceWorkshop(EquipmentEnergyParam equipmentEnergyParam) {
        Map<String, PurchasingBody> respMap = new HashMap<>();
        // 能耗统计
        List<PurchasingBody> purchaseEnergyList = consumptionDao.energyPriceMapCaChe(1, equipmentEnergyParam.getBegin(), equipmentEnergyParam.getEnd());
        if (org.apache.commons.collections4.CollectionUtils.isEmpty(purchaseEnergyList)) {
            return respMap;
        }
        SimpleDateFormat sdf = null;
        if (TimeDimensionEnum.YEAR.getCode().equals(equipmentEnergyParam.getDateType())) {
            sdf = new SimpleDateFormat("yyyy-MM");
        } else {
            sdf = new SimpleDateFormat("yyyy-MM-dd");
        }
        for (PurchasingBody purchasingBody : purchaseEnergyList) {
            respMap.put(sdf.format(purchasingBody.getDateAll()) + purchasingBody.getType() + purchasingBody.getWorkshopId(), purchasingBody);
        }
        return respMap;
    }

    @Cacheable("purchaseEnergy-building")
    public Map<String, PurchasingBody> energyPriceMapBuild(EquipmentEnergyParam equipmentEnergyParam) {
        Map<String, PurchasingBody> respMap = new HashMap<>();
        // 能耗统计
        List<PurchasingBody> purchaseEnergyList = consumptionDao.energyPriceMapCaChe(2, equipmentEnergyParam.getBegin(), equipmentEnergyParam.getEnd());
        if (org.apache.commons.collections4.CollectionUtils.isEmpty(purchaseEnergyList)) {
            return respMap;
        }
        SimpleDateFormat sdf = null;
        if (TimeDimensionEnum.YEAR.getCode().equals(equipmentEnergyParam.getDateType())) {
            sdf = new SimpleDateFormat("yyyy-MM");
        } else {
            sdf = new SimpleDateFormat("yyyy-MM-dd");
        }
        for (PurchasingBody purchasingBody : purchaseEnergyList) {
            respMap.put(sdf.format(purchasingBody.getDateAll()) + purchasingBody.getType() + purchasingBody.getBuildingId(), purchasingBody);
        }
        return respMap;
    }


}
